﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.IO.Compression;
using System.Xml.Serialization;
using System.Xml;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;

namespace DusonFramework.Core.Web
{
    public class SerializableObj<T> where T : IEnumerable
    {
        public static Byte[] Serialize(T obj)
        {
            try
            {
                MemoryStream ms = new MemoryStream();
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(ms, obj);
                ms.Position = 0;
                byte[] buffers = ms.ToArray();
                ms.Close();
                ms.Dispose();

                return Compress(buffers);
            }
            catch (Exception ex) 
            { 
                throw ex; 
            }
        }

        public static byte[] Compress(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream();
            GZipStream gzip = new GZipStream(ms, CompressionMode.Compress, true);
            gzip.Write(buffer, 0, buffer.Length);
            gzip.Close();
            ms.Position = 0;
            byte[] rebuffer = new byte[ms.Length];
            ms.Read(rebuffer, 0, int.Parse(ms.Length.ToString()));

            return rebuffer;
        }
    }

    public class Deserizlize<T> where T : class,IEnumerable
    {
        public static byte[] Decompress(byte[] buffer)
        {
            try
            {
                MemoryStream ms = new MemoryStream(buffer);
                ms.Position = 0;
                GZipStream gzip = new GZipStream(ms, CompressionMode.Decompress);
                byte[] rebuffer = new byte[100];
                MemoryStream msre = new MemoryStream();
                int readcont = gzip.Read(rebuffer, 0, rebuffer.Length);
                while (readcont > 0)
                {
                    msre.Write(rebuffer, 0, readcont);
                    readcont = gzip.Read(rebuffer, 0, rebuffer.Length);
                }

                return msre.ToArray();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public static T Deserilize(byte[] buffer)
        {
            try
            {
                byte[] debuffer = Decompress(buffer);
                BinaryFormatter bf = new BinaryFormatter();
                MemoryStream ms = new MemoryStream(debuffer);
                ms.Position = 0;
                T obj = bf.Deserialize(ms) as T;

                return obj;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

    public static class SerializableHelper
    {
        public static T BinaryDeserialize<T>(string str) where T : class
        {
            T local = default(T);
            if (str.Length > 0)
            {
                try
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    MemoryStream serializationStream = new MemoryStream(Encoding.Unicode.GetBytes(str))
                    {
                        Position = 0L
                    };
                    serializationStream.Seek(0L, SeekOrigin.Begin);
                    local = formatter.Deserialize(serializationStream) as T;
                }
                catch (Exception exception)
                {
                    throw exception;
                }
            }
            return local;
        }

        public static string BinarySerialize(object obj)
        {
            string str = null;
            if (obj != null)
            {
                try
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    MemoryStream serializationStream = new MemoryStream();
                    formatter.Serialize(serializationStream, obj);
                    str = Encoding.Unicode.GetString(serializationStream.GetBuffer());
                }
                catch (Exception exception)
                {
                    throw exception;
                }
            }
            return str;
        }

        public static T DataContractDeSerialize<T>(string str) where T : class
        {
            T local = default(T);
            if (str.Length > 0)
            {
                try
                {
                    MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(str))
                    {
                        Position = 0L
                    };
                    stream.Seek(0L, SeekOrigin.Begin);
                    DataContractSerializer serializer = new DataContractSerializer(typeof(T));
                    local = (T)serializer.ReadObject(stream);
                    stream.Close();
                }
                catch (Exception exception)
                {
                    throw exception;
                }
            }
            return local;
        }

        public static string DataContractSerialize(object obj)
        {
            string str = null;
            if (obj != null)
            {
                try
                {
                    MemoryStream stream = new MemoryStream();
                    new DataContractSerializer(obj.GetType()).WriteObject(stream, obj);
                    stream.Position = 0L;
                    str = new StreamReader(stream).ReadToEnd();
                }
                catch (Exception exception)
                {
                    throw exception;
                }
            }
            return str;
        }

        public static string GenXml(object Obj)
        {
            XmlDocument document = new XmlDocument();
            XmlElement newChild = document.CreateElement("AllInfo");
            PropertyInfo[] properties = Obj.GetType().GetProperties();
            foreach (PropertyInfo info in properties)
            {
                System.Xml.XmlNode node = document.CreateElement(info.Name);
                node.InnerText = Convert.ToString(info.GetValue(Obj, null));
                newChild.AppendChild(node);
            }
            document.AppendChild(newChild);
            return document.InnerXml;
        }

        public static T NetDataContractDeSerialize<T>(string str) where T : class
        {
            T local = default(T);
            if (str.Length > 0)
            {
                try
                {
                    MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(str))
                    {
                        Position = 0L
                    };
                    stream.Seek(0L, SeekOrigin.Begin);
                    NetDataContractSerializer serializer = new NetDataContractSerializer();
                    local = (T)serializer.ReadObject(stream);
                    stream.Close();
                }
                catch (Exception exception)
                {
                    throw exception;
                }
            }
            return local;
        }

        public static string NetDataContractSerialize(object obj)
        {
            string str = null;
            if (obj != null)
            {
                try
                {
                    MemoryStream stream = new MemoryStream();
                    new NetDataContractSerializer().WriteObject(stream, obj);
                    stream.Position = 0L;
                    str = new StreamReader(stream).ReadToEnd();
                }
                catch (Exception exception)
                {
                    throw exception;
                }
            }
            return str;
        }

        public static T SoapDeserialize<T>(string Str) where T : class
        {
            T local = default(T);
            try
            {
                IFormatter formatter = new SoapFormatter();
                Stream serializationStream = new MemoryStream(Convert.FromBase64String(Str));
                local = formatter.Deserialize(serializationStream) as T;
                serializationStream.Close();
                serializationStream.Dispose();
            }
            catch (Exception)
            {
                return default(T);
            }
            return local;
        }

        public static string SoapSerializable(object Obj)
        {
            string str = string.Empty;
            try
            {
                IFormatter formatter = new SoapFormatter();
                Stream serializationStream = new MemoryStream();
                formatter.Serialize(serializationStream, Obj);
                byte[] buffer = new byte[serializationStream.Length];
                serializationStream.Position = 0L;
                serializationStream.Read(buffer, 0, buffer.Length);
                str = Convert.ToBase64String(buffer);
                serializationStream.Close();
                serializationStream.Dispose();
            }
            catch (Exception exception)
            {
                throw exception;
            }
            return str;
        }

        public static T XmlDeserialize<T>(string serializedString) where T : class
        {
            T local2;
            if (serializedString.Trim().Equals(string.Empty))
            {
                throw new Exception("传入的序列化字符串为空");
            }
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(T));
                StringReader textReader = new StringReader(serializedString);
                T local = serializer.Deserialize(textReader) as T;
                local2 = local;
            }
            catch (Exception exception)
            {
                throw exception;
            }
            return local2;
        }

        public static string XmlSerialize(object obj)
        {
            StreamWriter writer = null;
            string str = null;
            try
            {
                XmlSerializer serializer = new XmlSerializer(obj.GetType());
                MemoryStream stream = new MemoryStream();
                writer = new StreamWriter(stream);
                serializer.Serialize((TextWriter)writer, obj);
                stream.Position = 0L;
                str = Encoding.UTF8.GetString(stream.GetBuffer());
            }
            catch (Exception exception)
            {
                throw exception;
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }
            }
            return str;
        }
    }

}

